import { Inject, Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import SysMenu from '@main/entities/service/admin/sys/sys-menu.entity';
import { Repository,IsNull, Not } from 'typeorm';
import { SysRoleService } from '../role/role.service';
import { ROOT_ROLE_ID } from '@main/service/modules/admin/admin.constants';
import { concat, includes, isEmpty, uniq } from 'lodash';

@Injectable()
export class SysMenuService {
  constructor(
    @InjectRepository(SysMenu) private menuRepository: Repository<SysMenu>,
    @Inject(ROOT_ROLE_ID) private rootRoleId: number,
    private roleService: SysRoleService,
  ) {}

  /**
   * 查找所有菜单
   */
  async findAllMenu() {
    return await this.menuRepository.find();
  }

  /**
   * 删除所有菜单
   */
  async removeAllMenu() {
    return await this.menuRepository.clear();
  }

  /**
   * 新增所有菜单
   */
  async addAllMenu(list) {
    return await this.menuRepository.save(list);
  }

  /**
   * 根据角色获取所有菜单
   */
  async getMenus(uid: string): Promise<SysMenu[]> {
    const roleIds = await this.roleService.getRoleIdByUser(uid);
    let menus: SysMenu[] = [];

    if (includes(roleIds, this.rootRoleId.toString())) {
      // root find all
      menus = await this.menuRepository.find();
    } else {
      // [ 1, 2, 3 ] role find
      menus = await this.menuRepository
        .createQueryBuilder('menu')
        .innerJoinAndSelect(
          'sys_role_menu',
          'role_menu',
          'menu.menu_code = role_menu.menu_code',
        )
        .andWhere('role_menu.role_id IN (:...roldIds)', { roldIds: roleIds })
        .getMany();
    }

    return menus;
  }

  /**
   * 获取当前用户的所有权限
   */
  async getPerms(uid: string): Promise<string[]> {
    const roleIds = await this.roleService.getRoleIdByUser(uid);
    let perms: any[] = [];
    let result: any = null;
    if (includes(roleIds, this.rootRoleId.toString())) {
      // root find all perms
      result = await this.menuRepository.find({
        where: { url: Not(IsNull()) },
      });
    } else {
      result = await this.menuRepository
        .createQueryBuilder('menu')
        .innerJoinAndSelect(
          'sys_role_menu',
          'role_menu',
          'menu.menu_code = role_menu.menu_code',
        )
        .andWhere('role_menu.role_id IN (:...roldIds)', { roldIds: roleIds })
        .andWhere('menu.url IS NOT NULL')
        .getMany();
    }
    if (!isEmpty(result)) {
      result.forEach((e) => {
        if(e.url){
          perms = concat(perms, e.url.split(','));
        }
      });
      perms = uniq(perms);
    }
    return perms;
  }
}
